//	------------------------------------------------------------------------------------------------
//	File name:		PdbParser.cpp
//	Author:			Marc Ochsenmeier
//	Email:			marc@ochsenmeier.de
//	Web:			www.breakpoints.de - 
//	Date:			02.07.2009
//
//	Description:	This file contains the entry points of our PDB interfaces accessors schema.
//
//	------------------------------------------------------------------------------------------------
#include "stdafx.h"

#include "PdbTranslationMaps.h"
#include "PdbFile.h"
#include "PdbParserInternal.h"

//	Global
CPdbParser* pIPdbParser = NULL;

//	Statics
CPdbFile* CPdbParser::m_pIPdbFile = NULL;
CPdbDump* CPdbParser::pPdbDump = NULL;

IPdbParser* IPdbParserFactory::Create(bool bCreateDumpFile)
{
	//	Initialize Appartment
	HRESULT hr = CoInitialize(NULL);

	// Access the DIA provider
	IDiaDataSource* pIDiaDataSource = NULL;
	hr = CoCreateInstance(__uuidof(DiaSource), 
		NULL, CLSCTX_INPROC_SERVER, 
		__uuidof(IDiaDataSource), 
		(void**)&pIDiaDataSource);
	if(FAILED(hr)) 
	{
		throw -1;
	}
	else
	{
		if(pIPdbParser==NULL)
		{
			pIPdbParser = new CPdbParser(pIDiaDataSource, false); 
		}
	}
	_ASSERTE(pIPdbParser);
	return pIPdbParser;
}
void IPdbParserFactory::Destroy()
{
	delete pIPdbParser;
	pIPdbParser = NULL;
	
	//	Leave COM appartment
	CoUninitialize();
}
CPdbParser::CPdbParser(IDiaDataSource* pIDiaDataSource, bool bCreateDumpFile) : 
	m_pIDiaDataSource(pIDiaDataSource)
{
}
CPdbParser::~CPdbParser()
{
	if(pPdbDump)
	{
		delete pPdbDump;
		pPdbDump = NULL;
	}

	if(m_pIPdbFile)
	{
		delete m_pIPdbFile;
		m_pIPdbFile = NULL;
	}

	if (m_pIDiaDataSource) 
	{
		m_pIDiaDataSource->Release();
		m_pIDiaDataSource = NULL;
	}
}
IDiaDataSource* CPdbParser::GetDiaDataSource() const
{
	return m_pIDiaDataSource;
}

IPdbFile* CPdbParser::OpenFile(const std::wstring& path)
{
	try
	{
		if(&path!=NULL)
		{
			//	Close previous one.
			if(m_pIPdbFile)
			{
				delete m_pIPdbFile;
				m_pIPdbFile = NULL;
			}

			m_pIPdbFile = new CPdbFile(this, path);
			if(m_pIPdbFile->Load(path)==false)
			{
				//	the PDB file has NOT been found
				delete m_pIPdbFile;
				m_pIPdbFile = NULL;
			}
		}
	}
	catch(...)
	{
		delete m_pIPdbFile;
		m_pIPdbFile = NULL;
	}
	return m_pIPdbFile;
}